package com.my.demo.config;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StreamUtils;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.sql.ResultSet;
import java.util.*;

/**
 * @Description 权限过滤器
 * @Author MR.Z
 * @CreateTime 2019/07/18 22:51
 */
@Order(value = 1000)
@Configuration
@Slf4j
@WebFilter(value = "/*")
public class AuthFilter implements Filter {

//    @Autowired
//    private DCEZProperties dcezProperties;

//    @Resource
//    private AntPathMatcher antPathMatcher;

    @Override
    public void init(FilterConfig filterConfig) {
        log.info("权限过滤器初始化");
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//        HttpServletRequest req = (HttpServletRequest) request;

//        BodyReaderHttpServletRequestWrapper requestWrapper = new BodyReaderHttpServletRequestWrapper(req);

        boolean isDoFilter = false;

        BodyReaderHttpServletRequestWrapper requestWrapper = null;
        if (request instanceof HttpServletRequest) {
            HttpServletRequest req = (HttpServletRequest) request;
            requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
            log.info("接收到请求url={}", req.getRequestURI());
//            String token = requestWrapper.getHeader(DCEZConstant.COM_DCEZ_TOKEN);
//            if (StringUtils.isNotBlank(token) && !"null".equals(token)) {
//                UserInfo userInfo;
//                try {
//                    userInfo = JWTUtil.unsign(token, UserInfo.class, dcezProperties.getJwtSecret());
//                } catch (Exception e) {
//                    log.info("接收到请求url={},token无效,token={}", req.getRequestURI(), token);
//                    ResultSet error = ResultSet.error(CodeEnum.TOKEN_ERROR, "无访问权限", "token无效");
//                    createResponse(response, error);
//                    return;
//                }
//
//                assert userInfo != null;
//                if (userInfo.getUserType().equals(UserTypeEnum.USER)) {
//                    requestWrapper.addHeader(DCEZConstant.USER_ID, userInfo.getUserId().toString());
//                }
//
//                log.info("接收到请求url={},从token中解析出的用户信息={},token={}", req.getRequestURI(), JSONObject.toJSONString(userInfo), token);
//            } else {
//                String[] excludeUrlList = dcezProperties.getExcludeUrl();
//                String requestURI = req.getRequestURI();
//                for (String excluUrl : excludeUrlList) {
//                    if (antPathMatcher.match(excluUrl, requestURI)) {    //该路径配置了白名单,放行
//                        isDoFilter = true;
//                        log.info("接收到请求url={},该路径为白名单(无需做权限校验)", req.getRequestURI());
//                        break;
//                    }
        }
//                if (!isDoFilter) {
//                    log.info("接收到请求url={},未传入token,token={}", req.getRequestURI(), token);
//                    ResultSet error = ResultSet.error(CodeEnum.TOKEN_ERROR, "无访问权限", "请传入token");
//                    createResponse(response, error);
//                    return;
//                }
//            }
//        }


        //从请求头中获取token
        if (requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
//        chain.doFilter(requestWrapper, response);
    }


    /**
     * @Description 响应
     * @Author MR.Z
     * @CreateTime 2019/07/18 23:54
     * @Params [response, resultset]
     * @Return void
     */
    private void createResponse(ServletResponse response, ResultSet resultset) throws IOException {
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setStatus(200);
        resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8);
        PrintWriter printWriter = new PrintWriter(outputStreamWriter, true);
        String jsonStr = JSON.toJSONString(resultset, SerializerFeature.WriteMapNullValue);
        printWriter.write(jsonStr);
        printWriter.flush();
        printWriter.close();
        outputStreamWriter.close();
    }

    @Override
    public void destroy() {

    }

    public static class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

        private byte[] requestBody = null;//用于将流保存下来

        private final Map<String, String> headerMap = new HashMap<>();

        public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            requestBody = StreamUtils.copyToByteArray(request.getInputStream());
            String body = new String(requestBody, request.getCharacterEncoding());
            String queryString = request.getQueryString();
            log.info("请求参数:{} , 请求体：{} ", queryString, body);
//            log.info("请求参数:{} ", queryString);
        }

        @Override
        public ServletInputStream getInputStream() {

            final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);

            return new ServletInputStream() {

                @Override
                public int read() {
                    return bais.read();
                }

                @Override
                public boolean isFinished() {
                    return false;
                }

                @Override
                public boolean isReady() {
                    return false;
                }

                @Override
                public void setReadListener(ReadListener readListener) {

                }
            };
        }


        void addHeader(String name, String value) {
            headerMap.put(name, value);
        }

        @Override
        public String getHeader(String name) {
            String headerValue = super.getHeader(name);
            if (headerMap.containsKey(name)) {
                headerValue = headerMap.get(name);
            }
            return headerValue;
        }

        @Override
        public Enumeration<String> getHeaderNames() {
            List<String> names = Collections.list(super.getHeaderNames());
            names.addAll(headerMap.keySet());
            return Collections.enumeration(names);
        }

        @Override
        public Enumeration<String> getHeaders(String name) {
            List<String> values = Collections.list(super.getHeaders(name));
            if (headerMap.containsKey(name)) {
                values.add(headerMap.get(name));
            }
            return Collections.enumeration(values);
        }

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
    }

    /**
     * @Description 用户信息
     * @Author MR.Z
     * @CreateTime 2019/07/09 9:54
     */
//    @Data
//    @AllArgsConstructor
//    @NoArgsConstructor
//    @ToString
//    @EqualsAndHashCode
//    public static class UserInfo {
//        private Integer userId;  //用户id
//        private UserTypeEnum userType;    //用户类型
//    }
}
